/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.repair.controller;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.DictCache;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.TenantIgnore;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.MaintainPlanContentEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.repair.vo.*;
import org.springblade.modules.repair.vo.part.SearchPartsTreeVo;
import org.springblade.modules.repair.vo.plan.PlanPartStatusVo;
import org.springblade.modules.repair.vo.plan.wx.WxUserPlanVo;
import org.springblade.modules.system.entity.Dict;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 故障工单明细 控制器
 *
 * @author zcc
 * @since 2021-05-22
 */
@RestController
@AllArgsConstructor
@RequestMapping("repair/maintain/malfunction/work")
@Api(value = "故障工单管理", tags = "故障工单管理")
public class MaintainMalfunctionWorkController extends BladeController {

	private final IMaintainMalfunctionWorkService maintainMalfunctionWorkService;
	private final IMaintainMalfunctionHistoryService malfunctionHistoryService;

	private final IMaintainPlanContentService maintainPlanContentService;
	private final MaintainPartsService maintainPartsService;
	private final IMaintainPlanRelationService maintainPlanRelationService;
	private final IMaintainPlanContentExtService maintainPlanContentExtService;

	/**
	 * 查询维修任务详情
	 *
	 * @param planId
	 * @return
	 */
	@ApiLog("维修-工单详情")
	@GetMapping("/detail")
	public R<MalFunctionDetailVO> malfunctionDetail(Long planId) {
		return R.data(maintainMalfunctionWorkService.malfunctionDetail(planId));
	}

	/**
	 * 审核列表查询维修详情
	 *
	 * @param planId
	 * @return
	 */
	@GetMapping("/approve/detail")
	public R<MalFunctionApproveDetailVO> malfunctionApproveDetail(Long planId) {
		return R.data(maintainMalfunctionWorkService.malfunctionApproveDetail(planId));
	}

	/**
	 * 新增或修改维修工单历史项
	 *
	 * @param malfunctionHistory
	 * @return
	 */
	@ApiLog("维修/配件/事务-记录更新")
	@PostMapping("/update/history")
	public R<Long> updateHistory(@RequestBody MaintainMalfunctionHistory malfunctionHistory) {
		return R.data(malfunctionHistoryService.updateHistory(malfunctionHistory));
	}

	/**
	 * 删除维修工单历史项
	 *
	 * @param ids
	 * @return
	 */
	@DeleteMapping("/remove/history")
	public R<Boolean> removeHistory(String ids) {
		Long id = Convert.toLong(ids.split(",")[0]);
		MaintainMalfunctionHistory malfunctionHistory = malfunctionHistoryService.getById(id);
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(malfunctionHistory.getPlanId());
		if (maintainPlanContent.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_WX.getId() && maintainPlanContent.getStatus() == TaskStatusEnum.WX_SIGN_FINISH.getStatus()) {
			List<MaintainMalfunctionHistory> historyList = malfunctionHistoryService.list(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getWorksId, malfunctionHistory.getWorksId()));
			if (historyList.size() == 1) {
				return R.fail("维修记录最后一条不可删除");
			}
		}
		return R.status(malfunctionHistoryService.removeByIds(Func.toLongList(ids)));
	}

	/**
	 * 获取报障故障现象
	 *
	 * @return
	 */
	@GetMapping("/problem/item")
	public R<?> problemItem() {
		List<Dict> problemVal = DictCache.getList("fault_problem");
		problemVal.sort(Comparator.comparing(Dict::getSort));
		return R.data(problemVal);
	}

	/**
	 * 获取报障故障现象
	 *
	 * @return
	 */
	@GetMapping("/fault/reason")
	public R<?> faultReason() {
		List<Dict> problemVal = DictCache.getList("fault_reason");
		List<Dict> list = new ArrayList<>(16);
		for (Dict dict : problemVal) {
			if (!(dict.getDictValue().contains("设计缺陷") || dict.getDictValue().contains("调整不当"))) {
				list.add(dict);
			}
		}
		return R.data(list);
	}

	/**
	 * 新增报障
	 */
	@ApiLog("维修-维修工单新增")
	@PostMapping("/malfunctionWorkSave")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "新增报障", notes = "传入repairWorkVO")
	public R<HashMap<String, Object>> malfunctionWorkSave(@Valid @RequestBody RepairWorkVO repairWorkVO) {
		return R.data(maintainMalfunctionWorkService.malfunctionWorkSave(repairWorkVO));
	}

	/**
	 * 重新分配任务
	 */
	@PostMapping("/malfunctionWorkUpdate")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "重新分配任务", notes = "传入repairWorkVO")
	public R<Boolean> malfunctionWorkUpdate(@Valid @RequestBody RepairWorkVO repairWorkVO) {
		return R.status(maintainMalfunctionWorkService.malfunctionWorkUpdate(repairWorkVO));
	}


	/**
	 * 维修完成
	 *
	 * @param malfunctionWork
	 * @return
	 */
	@TenantIgnore
	@PostMapping("/finish")
	public R<Boolean> finish(@RequestBody MaintainMalfunctionWork malfunctionWork) {
		return R.status(maintainMalfunctionWorkService.malfunctionFinish(malfunctionWork));
	}

	/**
	 * 获取维修工单状态
	 *
	 * @return
	 */
	@GetMapping("/plan/status")
	public R<List<TaskStatusVO>> selectMalPlanStatus() {
		return R.data(TaskStatusEnum.getTaskStatusByType(MaintainPlanContentEnum.MAINTAIN_WX.getId()));
	}

	/**
	 * 获取维修部件
	 *
	 * @return
	 */
	@TenantIgnore
	@GetMapping("/parts/tree")
	public R<List<MalfunctionPartsTreeVO>> selectMalPartsTree(String keyWord) {
		return R.data(maintainMalfunctionWorkService.selectMalPartsTree(keyWord));
	}


	/**
	 * 获取维修部件
	 *
	 * @return
	 */
	@TenantIgnore
	@GetMapping("/parts/tree/v2")
	public R<List<SearchPartsTreeVo>> selectMalPartsTreeV2(String keyWord) {
		return R.data(maintainMalfunctionWorkService.selectMalPartsTreeV2(keyWord));
	}


	/**
	 * 获取维修部件
	 *
	 * @return
	 */
	@TenantIgnore
	@GetMapping("/parts/list/parentId")
	public R<List<MaintainParts>> partsListOfParentId(Long parentId) {
		return R.data(maintainPartsService.list(Wrappers.<MaintainParts>lambdaQuery().eq(MaintainParts::getParentId, parentId)));
	}


	/**
	 * 根据工单id获取配件任务(未完成的)
	 *
	 * @param planId 工单id
	 * @return 数据集
	 */
	@GetMapping("getPartListCounts")
	@ApiOperation(value = "根据维修id获取未完成的配件数量")
	public R<PlanPartStatusVo> getPartListCounts(Long planId) {
		return R.data(maintainMalfunctionWorkService.getPartListCounts(planId));
	}

	/**
	 * 根据工单id获取配件任务
	 *
	 * @param planId 工单id
	 * @return 数据集
	 */
	@GetMapping("/getPartList")
	@ApiOperation(value = "根据工单id获取配件任务")
	public R<List<MaintainPlanContent>> getPartList(Long planId) {
		return R.data(maintainMalfunctionWorkService.getPartList(planId));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 更新维修详情
	 * }
	 * @Date 15:29 2023/4/7
	 * @Param
	 **/
	@PostMapping("/update")
	public R<Boolean> updateMalDetail(@RequestBody MaintainMalfunctionWork malfunctionWork) {
		return R.data(maintainMalfunctionWorkService.updateMalDetail(malfunctionWork));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 更新维修详情
	 * }
	 * @Date 15:29 2023/4/7
	 * @Param
	 **/
	@PostMapping("/submit")
	public R<Long> submitMalDetail(@RequestBody MaintainMalfunctionWork malfunctionWork) {
		return R.data(maintainMalfunctionWorkService.submitMalDetail(malfunctionWork));
	}

	@DeleteMapping("/remove")
	public R<Boolean> removeMalDetail(String ids, Long planId) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
		if (maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())) {
			List<MaintainMalfunctionWork> malfunctionWorkList = maintainMalfunctionWorkService.list(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, planId));
			List<MaintainMalfunctionWork> workList = malfunctionWorkList.stream().filter(o -> o.getPartsIds() != null && !o.getPartsIds().equals("0")).collect(Collectors.toList());
			if (workList.size() == 1) {
				return R.fail("维修配件最后一条不可删除");
			}
		}
		malfunctionHistoryService.remove(Wrappers.<MaintainMalfunctionHistory>lambdaQuery()
			.eq(MaintainMalfunctionHistory::getPlanId, planId).in(MaintainMalfunctionHistory::getWorksId, Func.toLongList(ids)));
		return R.data(maintainMalfunctionWorkService.removeByIds(Func.toLongList(ids)));
	}

	@GetMapping("/remove/result")
	@ApiOperation("维修删除结果判断")
	public R<Boolean> removeMalResult(Long planId) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
		if (maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())) {
			List<MaintainMalfunctionWork> malfunctionWorkList = maintainMalfunctionWorkService.list(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, planId));
			List<MaintainMalfunctionWork> workList = malfunctionWorkList.stream().filter(o -> o.getPartsIds() != null && !o.getPartsIds().equals("0")).collect(Collectors.toList());
			if (workList.size() == 1) {
				return R.fail("维修结果最后一条不可删除,只能修改");
			}
		}
		return R.data(true);
	}


	@GetMapping("/isCheckPlan")
	public R<Boolean> isCheckPlan(@RequestParam Long planId, @RequestParam Integer type) {
		List<MaintainPlanRelation> maintainPlanRelations = maintainPlanRelationService.list(Wrappers.<MaintainPlanRelation>lambdaQuery().eq(MaintainPlanRelation::getOwnPlanId, planId));
		if (Func.isNotEmpty(maintainPlanRelations)) {
			List<Long> fromPlanIds = maintainPlanRelations.stream().map(MaintainPlanRelation::getFromPlanId).collect(Collectors.toList());
			List<MaintainPlanContent> maintainPlanContents = maintainPlanContentService.listByIds(fromPlanIds);
			if (maintainPlanContents.stream().anyMatch(maintainPlanContent -> maintainPlanContent.getTypeStatus() == type)) {
				return R.data(true);
			}
		}
		return R.data(false);
	}


	/**
	 * 用户今日的维修工单列表
	 * @return 数据集
	 */
	@GetMapping("user/planList/OfToday")
	public R<List<WxUserPlanVo>> userPlanListOfToday(String buildingIds) {
		List<WxUserPlanVo> list = maintainMalfunctionWorkService.userPlanListOfToday(buildingIds);
		if (list.size() > 0) {
			list = list.stream().filter(o -> o.getUserId().equals(AuthUtil.getUserId())).collect(Collectors.toList());
			return R.data(list);
		}
		return R.data(new ArrayList<>());
	}
}
